/*
 * Copyright (c) 2019.
 * Private license for beyondts.
 * Contact beyondts for using, beyondts999@163.com
 */

package net.beyondts.mplug.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * The annotation to define a method as a plugin method.
 * The parameter "extension" should be as same as the extension's id.
 */
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Plugin {

    public static final String AROUND = "[around]";
    public static final String BEFORE = "[before]";
    public static final String AFTER = "[after]";
    public static final String THROW = "[throw]";

    /**
     * The ID of the extension current plugin method matched.
     * You can add some period description before extension id by using [period]. period can be :
     *      1. "around" or "" as default, to replace extension method using plugin method
     *      2. "before" to execute plugin method before extension method executed
     *      3. "after" to execute plugin method after extension method executed. if this trigger used, in-parameters of plugin method should use the return object of extension method as the first one
     *      4. "throw" to execute plugin method only when extension method throws some throwable
     * @return
     */
    String extension();

    /**
     * 指定选择当前插件方法的条件计算方法，需要与compare参数共同使用。
     * 格式1：a:argName，a表示从方法参数中寻找，此时紧跟的为参数名称，如果该参数是个复杂对象，还可以继续使用.propertyName标识其下的属性名称，可多级，也可以使用.methodName()标识其下的栽个方法（不能有参数），仅一级
     * 格式2：s:beanName，s表示从springcontext中查找bean，此时紧跟的为bean在SpringContext中的名称，同样可以后续使用.propertyName或.methodName()
     * 推荐使用propertyName的方式，因为使用methodName()方式时，整个method会在有多个插件时被多次运算。
     * @return
     */
    String choose() default "";

    /**
     * 指定choose结果的比较值，choose的结果会全部转成String类型与compare值进行比较，如果相同，则启用当前插件。
     * @return
     */
    String compare() default "";
}
